package com.yt.sys.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.yt.common.enums.CodeEnum;
import com.yt.common.exception.BusinessException;
import com.yt.product.common.config.YmlConfig;
import com.yt.sys.models.bo.SysUserRoleBO;
import com.yt.sys.models.bo.SysUserRoleReplaceBO;
import com.yt.sys.models.dto.SysRoleDTO;
import com.yt.sys.models.service.ISysRoleService;
import com.yt.sys.models.vo.SysUserRoleVO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import javax.annotation.Resource;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yt.sys.mapper.SysUserRoleMapper;
import com.yt.sys.models.service.ISysUserRoleService;
import com.yt.sys.models.bo.SysUserRoleSaveBO;
import com.yt.sys.models.dto.SysUserRoleDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户角色信息控制器
 *
 * @author chen
 * @Date 2025-09-05 18:51:40
 */
@DubboService
@Service
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRoleDTO> implements ISysUserRoleService {

    @Resource
    private YmlConfig ymlConfig;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @DubboReference
    private ISysRoleService sysRoleService;

    @Override
    public boolean add(SysUserRoleSaveBO saveBO) {
        // 参数校验
        validateSaveBO(saveBO);

        // 校验关联关系是否已存在
        checkDuplicate(saveBO.getUserId(), saveBO.getRoleId());

        // BO转DTO
        SysUserRoleDTO dto = new SysUserRoleDTO();
        BeanUtils.copyProperties(saveBO, dto);
        setDefaultValues(dto);

        // 设置主键
        dto.setId(ymlConfig.getPkId());
        return this.insert(dto);
    }


    @Override
    public List<SysUserRoleVO> selectByUserId(Long userId) {
        if (userId == null) {
            throw new BusinessException(CodeEnum.FAIL_100002.getCode(), "用户ID不能为空");
        }
        return sysUserRoleMapper.selectUserRoleVOByUserId(userId); // 调用联表查询
    }

    // 根据角色ID查询（联表返回VO）
    @Override
    public List<SysUserRoleVO> selectByRoleId(Long roleId) {
        if (roleId == null) {
            throw new BusinessException(CodeEnum.FAIL_100002.getCode(), "角色ID不能为空");
        }
        return sysUserRoleMapper.selectUserRoleVOByRoleId(roleId); // 调用联表查询
    }


    // 联表分页查询方法
    @Override
    public Page<SysUserRoleVO> selectUserRolePage(Page<SysUserRoleVO> page, SysUserRoleBO bo) {
        List<SysUserRoleVO> records = sysUserRoleMapper.selectUserRolePage(page, bo);
        return page.setRecords(records);
    }

    /**
     * 参数校验
     */
    private void validateSaveBO(SysUserRoleSaveBO saveBO) {
        if (saveBO == null) {
            throw new BusinessException(CodeEnum.FAIL_100001.getCode(), "用户角色关联信息不能为空");
        }
        if (saveBO.getUserId() == null) {
            throw new BusinessException(CodeEnum.FAIL_100002.getCode(), "用户ID不能为空");
        }
        if (saveBO.getRoleId() == null) {
            throw new BusinessException(CodeEnum.FAIL_100002.getCode(), "角色ID不能为空");
        }
    }

    /**
     * 检查关联关系是否重复
     */
    private void checkDuplicate(Long userId, Long roleId) {
        int count = this.selectCount(new EntityWrapper<SysUserRoleDTO>()
                .eq("user_id", userId)
                .eq("role_id", roleId));
        if (count > 0) {
            throw new BusinessException(CodeEnum.FAIL_100011.getCode(), "用户已关联该角色，请勿重复添加");
        }
    }

    /**
     * 设置默认值
     */
    private void setDefaultValues(SysUserRoleDTO dto) {
        Date now = new Date();
        dto.setRevision(dto.getRevision() != null ? dto.getRevision() : 0);
        dto.setCreateTime(dto.getCreateTime() != null ? dto.getCreateTime() : now);
        dto.setUpdateTime(dto.getUpdateTime() != null ? dto.getUpdateTime() : now);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean replaceUniqueRole(SysUserRoleReplaceBO replaceBO) {
        // 参数校验
        if (replaceBO.getUserId() == null) {
            throw new BusinessException(CodeEnum.FAIL_100002.getCode(), "用户ID不能为空");
        }
        if (replaceBO.getRoleId() == null) {
            throw new BusinessException(CodeEnum.FAIL_100002.getCode(), "角色ID不能为空");
        }

        // 校验角色是否存在
        SysRoleDTO role = sysRoleService.selectById(replaceBO.getRoleId());
        if (role == null) {
            throw new BusinessException(CodeEnum.FAIL_100011.getCode(), "角色不存在");
        }

        // 删除用户现有角色
        EntityWrapper<SysUserRoleDTO> deleteWrapper = new EntityWrapper<>();
        deleteWrapper.eq("user_id", replaceBO.getUserId());
        this.delete(deleteWrapper);

        //新增唯一角色关联
        Date now = new Date();
        SysUserRoleDTO newRole = new SysUserRoleDTO();
        newRole.setId(ymlConfig.getPkId());
        newRole.setUserId(replaceBO.getUserId());
        newRole.setRoleId(replaceBO.getRoleId());
        newRole.setRevision(0);
        newRole.setCreateTime(now);
        newRole.setUpdateTime(now);

        return this.insert(newRole);
    }
}